package com.codefalse.mybatis.gen;

import com.codefalse.mybatis.gen.model.TableModel;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.generator.config.*;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class GenerateFactory {

    public static Configuration getConfiguration(String targetRuntime, JDBCConnectionConfiguration connConfig,
                                                 JavaModelGeneratorConfiguration modelConfig, JavaClientGeneratorConfiguration clientConfig,
                                                 SqlMapGeneratorConfiguration xmlConfig, CommentGeneratorConfiguration commentConfig, List<TableModel> tableModels,
                                                 Boolean enableLombok, Boolean enableModelColumn,
                                                 Boolean enableDynamicWhere) {
        Configuration config = new Configuration();
        //context
        Context context = new Context(ModelType.CONDITIONAL);
        context.setId("mybatisGen");
        context.setTargetRuntime(targetRuntime);
        context.setJava8Targeted(true);

        context.addProperty("javaFileEncoding", "UTF-8");
        context.addProperty("beginningDelimiter", "`");
        context.addProperty("endingDelimiter", "`");

        //@Mapper注解
        addPlugin(context, "org.mybatis.generator.plugins.MapperAnnotationPlugin");
        //去除注释，合并xml
        addPlugin(context, "org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin");
        //序列化
        addPlugin(context, "org.mybatis.generator.plugins.SerializablePlugin");
        //lombok
        if (enableLombok) {
            addPlugin(context, "com.softwareloop.mybatis.generator.plugins.LombokPlugin");
        }
        //生成自定义sql
        if (enableDynamicWhere) {
            addPlugin(context, "com.codefalse.mybatis.gen.plugin.ListByParamsPlugin");
            enableModelColumn = true;
        }
        //在实体类中映射表字段
        if (enableModelColumn) {
            addPlugin(context, "com.codefalse.mybatis.gen.plugin.ModelColumnPlugin");
        }

        //Java类型转换
        JavaTypeResolverConfiguration resolverConfiguration = new JavaTypeResolverConfiguration();
        resolverConfiguration.setConfigurationType("com.codefalse.mybatis.gen.CustomJavaTypeResolver");
        resolverConfiguration.addProperty("useJSR310Types", "true");
        context.setJavaTypeResolverConfiguration(resolverConfiguration);

        //JDBC
        context.setJdbcConnectionConfiguration(connConfig);
        //配置
        context.setJavaModelGeneratorConfiguration(modelConfig);
        context.setJavaClientGeneratorConfiguration(clientConfig);
        context.setSqlMapGeneratorConfiguration(xmlConfig);
        context.setCommentGeneratorConfiguration(commentConfig);
        //设置表
        buildTableConfiguration(context, tableModels);

        config.addContext(context);
        return config;
    }

    public static void buildTableConfiguration(Context context, List<TableModel> tableModels) {
        for (TableModel model : tableModels) {
            TableConfiguration tc = new TableConfiguration(context);
            tc.setDelimitIdentifiers(true);
            tc.setAllColumnDelimitingEnabled(true);
            if (StringUtils.isNotBlank(model.getPrimaryKey()) && model.isAutoIncrement()) {
                tc.setGeneratedKey(new GeneratedKey(
                        model.getPrimaryKey(),
                        "JDBC",
                        true, ""));
            }
            tc.setTableName(model.getTableName());
            //禁用Example
            tc.setCountByExampleStatementEnabled(false);
            tc.setDeleteByExampleStatementEnabled(false);
            tc.setSelectByExampleStatementEnabled(false);
            tc.setUpdateByExampleStatementEnabled(false);
            //基础查询
            tc.setInsertStatementEnabled(true);
            tc.setDeleteByPrimaryKeyStatementEnabled(true);
            tc.setUpdateByPrimaryKeyStatementEnabled(true);
            tc.setSelectByPrimaryKeyStatementEnabled(true);

            context.addTableConfiguration(tc);
        }
    }

    public static List<TableModel> buildTables(String database, String tableName, String url, String user, String password) {

        List<TableModel> tableModels = new ArrayList<>();

        Connection connection = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection(url, user, password);
            String queryTable = "select TABLE_NAME, COLUMN_NAME, EXTRA from information_schema.COLUMNS where COLUMN_KEY = 'PRI' and TABLE_SCHEMA = ? and TABLE_NAME like ?";
            PreparedStatement stmt = connection.prepareStatement(queryTable);
            stmt.setString(1, database);
            stmt.setString(2, tableName);
            ResultSet rs = stmt.executeQuery();
            while (rs.next()) {
                String name = rs.getString("TABLE_NAME");
                String pri = rs.getString("COLUMN_NAME");
                String extra = rs.getString("EXTRA");

                TableModel model = new TableModel();
                model.setTableName(name);
                model.setPrimaryKey(pri);
                model.setAutoIncrement("auto_increment".equalsIgnoreCase(extra));

                tableModels.add(model);
            }

            stmt.close();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {

            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return tableModels;
    }

    private static void addPlugin(Context context, String type) {
        PluginConfiguration plugin = new PluginConfiguration();
        plugin.addProperty("type", type);
        plugin.setConfigurationType(type);
        context.addPluginConfiguration(plugin);
    }

}
